import { default as Hls } from "hls.js"
import { Parser } from "m3u8-parser"
import "media-chrome"

const registerServiceWorker = async () => {
    await navigator.serviceWorker.register('sw.js', { scope: './' });
};

const task = async (taskList, taskTime) => {
    while (taskList.length > 0 && taskTime === latestTaskTime) {
        const temp = taskList.pop();
        if (temp === undefined) {
            return;
        }
        const { idx, url } = temp;
        await fetch(url);
        if (taskTime === latestTaskTime) {
            document.getElementById("block-list").children[idx].style.cssText = "background-color: green";
        }
    }
}

const m3u8Concat = (suffix) => {
    if (suffix.startsWith("http://") || suffix.startsWith("https://")) {
        return suffix;
    }
    for (let i = suffix.length - 1; i >= 0; i--) {
        if (suffix.charAt(i) === "/" && prefix.endsWith(suffix.substring(0, i + 1))) {
            return prefix + suffix.substring(i + 1);
        }
    }
    return prefix + suffix;
}

const m3u8Parse = async (url) => {
    const p = new Parser();
    try {
        p.push(await (await fetch(url)).text());
    } catch (e) {
        document.getElementById("msg").innerText = "资源无效或解析异常";
    }
    p.end();
    if (p.manifest.playlists !== undefined) {
        playlistsParse(p.manifest.playlists);
    } else if (p.manifest.segments !== undefined) {
        segmentsParse(p.manifest.segments);
    }
}

const playlistsParse = (playlists) => {
    if (playlists !== undefined) {
        const url = m3u8Concat(playlists[0].uri);
        prefix = url.substring(0, url.lastIndexOf("/") + 1);
        m3u8Parse(url);
    }
}

const segmentsParse = async (segments) => {
    if (segments !== undefined) {
        let taskList = [];
        for (let idx = segments.length - 1; idx >= 0; idx--) {
            document.getElementById("block-list").appendChild(document.createElement("div"));
            taskList.push({ idx: idx, url: m3u8Concat(segments[idx].uri) });
        }
        hls.loadSource(videoSrc);
        hls.attachMedia(video);
        latestTaskTime = new Date();
        await Promise.allSettled([
            task(taskList, latestTaskTime),
            task(taskList, latestTaskTime),
            task(taskList, latestTaskTime),
            task(taskList, latestTaskTime),
        ]);
    }
}

const clearCache = () => {
    document.getElementById("clear-cache").addEventListener("click", () => {
        navigator.serviceWorker.controller.postMessage({
            "command": "clearCache",
        })
    });
}

const startCache = () => {
    document.getElementById("start-cache").addEventListener("click", () => {
        document.getElementById("msg").innerText = "";
        document.getElementById("block-list").remove();
        let blockList = document.createElement("div");
        blockList.id = "block-list";
        document.body.appendChild(blockList);
        videoSrc = document.getElementById("m3u8-src").value.trim();
        prefix = videoSrc.substring(0, videoSrc.lastIndexOf("/") + 1);
        if (videoSrc.includes(".m3u8")) {
            m3u8Parse(videoSrc);
            document.getElementById("start-cache").innerText = "缓存";
        } else {
            document.getElementById("msg").innerText = "无效m3u8网址";
        }
    });
}

let videoSrc = "";
let prefix = "";
let latestTaskTime = new Date();
let hls = new Hls({ progressive: true });
if (!'serviceWorker' in navigator) {
    document.getElementById("msg").innerText = "浏览器不支持Service Worker";
    throw new Error();
}
clearCache();
registerServiceWorker();
startCache();